package cn.smile.config;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * zuul的熔断处理
 *
 * @Author: MaoSuyu
 * @User：John
 * @Date: 2019/6/3
 * @Time: 22:50
 * @Description: No Description
 */
@Configuration
public class ZuulConfig implements FallbackProvider {


    /**
     * 对哪个route进行熔断，如果是全部则使用 * 或者 null
     * @return
     */
    @Override
    public String getRoute() {
        return "*";
    }

    /**
     * 熔断后给客户端的响应
     * @param route
     * @param cause
     * @return
     */
    @Override
    public ClientHttpResponse fallbackResponse(final String route, final Throwable cause) {
        return new ClientHttpResponse() {
            /**
             * 网关向api服务请求是失败了，但是消费者客户端向网关发起的请求是OK的，
             * 不应该把api的404,500等问题抛给客户端
             * 网关和api服务集群对于客户端来说是黑盒子
             */
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            /**
             * 无效请求
             * @return
             * @throws IOException
             */
            @Override
            public int getRawStatusCode() throws IOException {
                //异常代码
                return HttpStatus.BAD_REQUEST.value();
            }

            @Override
            public String getStatusText() throws IOException {
                //返回异常的简单描述
                return HttpStatus.BAD_REQUEST.getReasonPhrase();
            }

            @Override
            public void close() {

            }

            /**
             * 返回具体错误消息
             * @return
             * @throws IOException
             */
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(("遇到错误："+cause.getCause().getMessage()+"       "+route).getBytes("UTF-8"));
            }

            /**
             * 返回的Http头
             * @return
             */
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders httpHeaders=new HttpHeaders();
                //返回内容的类型
                httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                //消息发送时间，也就是该请求返回给客户端时的时间
                httpHeaders.setDate(System.currentTimeMillis());

                //Pragma头域用来包含实现特定的指令，最常用的是Pragma:no-cache,即不缓存
                //httpHeaders.setPragma("no-cache");

                //close（告诉WEB服务器或者代理服务器，在完成本次请求的响应后，断开连接，不要等待本次连接的后续请求了）。
                //keepalive（告诉WEB服务器或者代理服务器，在完成本次请求的响应后，保持连接，等待本次连接的后续请求）。
                httpHeaders.setConnection("close");
                //缓存控制，不缓存
                httpHeaders.setCacheControl(CacheControl.noCache());
                return httpHeaders;
            }
        };
    }


}
